﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.Windows.Forms.Design;
using System.Windows.Forms;

namespace ProgNetComponents.Design.Designers
{
    internal sealed class ContextHelper : ITypeDescriptorContext, IWindowsFormsEditorService, IDisposable
    {
        DesignSurface designSurface = new DesignSurface();

        private IDesigner _Designer;
        private PropertyDescriptor _Property;
        private IComponentChangeService _ChangeService;
        private IComponentChangeService ChangeService
        {
            get
            {
                if (_ChangeService == null)
                    _ChangeService = (IComponentChangeService)this.GetService(typeof(IComponentChangeService));
                return _ChangeService;
            }
        }

        internal ContextHelper(IDesigner designer, PropertyDescriptor property)
        {
            _Designer = designer;
            _Property = property;
        }
        ~ContextHelper()
        {
            Dispose();
        }

        #region ITypeDescriptorContext Members

        public IContainer Container
        {
            get
            {
                if (_Designer.Component.Site != null)
                    return _Designer.Component.Site.Container;
                return null;
            }
        }

        public object Instance
        {
            get { return _Designer.Component; }
        }

        public void OnComponentChanged()
        {
            if (ChangeService != null)
                ChangeService.OnComponentChanged(this._Designer.Component, _Property, null, null);
        }

        public bool OnComponentChanging()
        {
            if (ChangeService != null)
            {
                try
                {
                    this.ChangeService.OnComponentChanging(_Designer.Component, _Property);
                }
                catch (CheckoutException ex)
                {
                    if (ex != CheckoutException.Canceled)
                        throw;
                    else
                        return false;
                }
                return true;
            }
            return false;
        }

        public PropertyDescriptor PropertyDescriptor
        {
            get { return _Property; }
        }

        #endregion

        #region IServiceProvider Members

        public object GetService(Type serviceType)
        {
            if (serviceType == typeof(ITypeDescriptorContext) || serviceType == typeof(IServiceProvider) ||
                serviceType == typeof(IWindowsFormsEditorService))
            {
                return this;
            }
            if (_Designer != null && _Designer.Component != null && _Designer.Component.Site != null)
                return _Designer.Component.Site.GetService(serviceType);
            else
                designSurface.GetService(serviceType);
            return null;
        }

        #endregion

        #region IWindowsFormsEditorService Members

        public void CloseDropDown()
        {
        }

        public void DropDownControl(System.Windows.Forms.Control control)
        {

        }

        public System.Windows.Forms.DialogResult ShowDialog(System.Windows.Forms.Form dialog)
        {
            IUIService uiService = (IUIService)this.GetService(typeof(IUIService));
            if (uiService != null)
                return uiService.ShowDialog(dialog);
            else
                return dialog.ShowDialog(_Designer.Component as IWin32Window);
        }

        #endregion

        #region IDisposable Members

        public void Dispose()
        {
            designSurface.Dispose();
        }

        #endregion
    }
}
